/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package biofilter.records;

import biofilter.util.MappedPosition;
import biofilter.util.StringUtil;
import java.text.ParseException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * BlastTabRecord holds single line blast results from blast.
 * example running of blastn:
 * blastall -a 4 -m 8 -p blastn -e 0.0001 -i ./testReads.fa -d /auto/transcriptomics/data/genomes/Bacteria/Clostridium_thermocellum_ATCC_27405/NC_009012 -o ./test.blast
 * @author Daniel Quest
 * @date   Feb 4 2010
 */
public class BlastTabRecord implements Record, MappedPosition {
    public BlastTabRecord(){

    }
    public BlastTabRecord(String s){
        this.set(s);
    }
    /**
     * #example tab deliminated output: 
    q - query the thing you are blasting
    d - the source database you are blasting against
    1. Query id (from the search)
    2. Subject id (from the formatdb database)
    3. % identity
    4. Alignment length
    5. Mismatches
    6. Gap openings
    7. Query start
    8. Query end
    9. Subject start
   10. Subject end
   11. E-value
   12. Bit score 
 HWI-EAS127_3_4_1_804_876        ctg93   100.00  38      0       0       1       38      421500  421463  5e-16   75.8
 q                               d       %identy #aLen   #missma #gapOpe qstart  qend    dstart  dend    E-Value Score
     * */
    private String query_id = null;
    private String subject_id = null;
    private Double percent_identity = Double.MIN_VALUE;
    private int alignment_length = Integer.MIN_VALUE;
    private int mismatches = Integer.MIN_VALUE;
    private int gap_openings = Integer.MIN_VALUE;
    private int query_start = Integer.MIN_VALUE;
    private int query_end = Integer.MIN_VALUE;
    private int subject_start = Integer.MIN_VALUE;
    private int subject_end = Integer.MIN_VALUE;
    private String e_value = null;
    private double bit_score = Double.MIN_VALUE;
    private String record = null;

    public String get() {
        return this.record;
    }

    public void set(String r) throws IllegalArgumentException {
        this.record = r;
    }
    
    private void parse(){
        
        try {
            Double dd = new Double("0");
            Integer ii = new Integer("0");
            StringUtil sute = new StringUtil();
            String tokens[] = sute.splitOnTab(this.record, 12);
            this.query_id = tokens[0].trim();
            this.subject_id = tokens[1].trim();
            this.percent_identity = dd.parseDouble(tokens[2]);
            this.alignment_length = ii.parseInt(tokens[3]);
            this.mismatches = ii.parseInt(tokens[4]);
            this.gap_openings = ii.parseInt(tokens[5]);
            this.query_start= ii.parseInt(tokens[6]);
            this.query_end= ii.parseInt(tokens[7]);
            this.subject_start= ii.parseInt(tokens[8]);
            this.subject_end = ii.parseInt(tokens[9]);
            this.e_value = tokens[10].trim();
            this.bit_score = dd.parseDouble(tokens[11].trim());
        } catch (ParseException ex) {
            Logger.getLogger(BlastTabRecord.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
   
    public int getStart() {
        if (this.subject_start == Integer.MIN_VALUE){ parse(); }
        return this.subject_start;
    }
    public int getQueryStart() {
        if (this.query_start == Integer.MIN_VALUE){ parse(); }
        return this.query_start;
    }


    public int getEnd() {
        if (this.subject_end == Integer.MIN_VALUE){ parse(); }
        return this.subject_end;
    }
    public int getQueryEnd() {
        if (this.query_end == Integer.MIN_VALUE){ parse(); }
        return this.query_end;
    }

    public int length() {
        if (this.alignment_length == Integer.MIN_VALUE){ parse(); }
        return this.alignment_length;
    }

    /**
     * Note: this version of get strand is to get the strand on the subject not the query.
     * @return
     */
    public char getStrand() {
        int qstart = this.getQueryStart();
        int qend = this.getQueryEnd();
        int sstart = this.getStart();
        int send = this.getEnd();
        if ( qstart <= qend && sstart <= send) return '+'; // +/+
        else if(qstart <= qend && sstart > send) return '-'; // +/-
        else if(qstart > qend && sstart <= send) return '-'; // -/+
        else return '+'; // -/-
    }

    public double getWeight() {
        if(this.bit_score == Double.MIN_VALUE ){parse();}
        return this.bit_score;
    }

    public String getQueryID() {
        if (this.query_id == null){ parse(); }
        return this.query_id;
    }

    public String getSubjectID() {
        if (this.subject_id == null){ parse(); }
        return this.subject_id;
    }
    
    public String getEvalue(){
        if (this.e_value == null){ parse(); }
        return this.e_value;
    }

}
